import { join } from 'path';
import * as URL from 'url';
import { isExist, exec, send, fileContain } from '../helper/utils';
import scripts from './scripts';
import { IOptionsWithUrl } from '.';

export default async (options: IOptionsWithUrl): Promise<void> => {
  const { REPO_NAME = '', TAG, REPO_ROOT = '' } = process.env;
  const fetchAndTag = `git fetch && git checkout tags/${TAG}`;

  // 项目的绝对路径
  const repoPath = join(REPO_ROOT, REPO_NAME);

  if (await isExist(repoPath, true)) {
    if (await isExist(join(repoPath, '.git/config'))) {
      try {
        send('git fetching...');
        const { stdout, stderr } = await exec(`git checkout . && ${fetchAndTag}`, {
          cwd: repoPath,
        });
        send(stderr);
        send(stdout);
        await scripts(repoPath, options);
      } catch (err) {
        send(err, false);
      }
    } else {
      send(`${repoPath} 地址已存在，且该目录不是git项目，请手动删除该目录`, false);
    }
  } else if (await isExist(REPO_ROOT, true)) {
    const { username, password, httpUrl, sshUrl } = options;
    let std;
    try {
      if (username && password && httpUrl) {
        send('正在使用http(s)+username+password克隆代码中...');
        const u = URL.parse(httpUrl);
        const url = `${u.protocol}//${username}:${password}@${u.host}${u.path}`
        std = await exec(`git clone ${url}`, { cwd: REPO_ROOT });
      } else if (sshUrl) {
        send('正在使用ssh克隆代码中...');
        const matched = sshUrl.match(/@([^:]+)/);
        if (matched) {
          const domain = matched[1];
          try {
            if (!await fileContain(domain)) {
              await exec(`ssh-keyscan ${domain} >> ~/.ssh/known_hosts`).catch(err => send(err.message));
            }
            std = await exec(`git clone ${sshUrl}`, { cwd: REPO_ROOT, timeout: 15 * 1000 });
          } catch (err) {
            send(err.message);
            send('正在尝试使用http(s)克隆代码');
            std = await exec(`git clone ${httpUrl}`, { cwd: REPO_ROOT });
          }
        }
      } else if (httpUrl) {
        send('正在使用http(s)克隆代码');
        std = await exec(`git clone ${httpUrl}`, { cwd: REPO_ROOT });
      }
    } catch (err) {
      send(err.message, false);
    }
    if (std) {
      send(std.stdout);
      send(std.stderr);
      const std1 = await exec(fetchAndTag, { cwd: join(REPO_ROOT, REPO_NAME) });
      send(std1.stdout);
      send(std1.stderr);
      await scripts(repoPath, options);
    }
  } else {
    send(`更新仓库失败，仓库所在根目录不存在`, false);
  }
}
